﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HA.ModFlow.Domain.DomainLayer
{
    [Serializable]
    public class UZF : MFBoundary, ICloneable
    {


        #region 构造函数

        public UZF(int nrows, int ncolumns, int nlayers, int nPeriods)
            : base(nrows, ncolumns, nlayers, nPeriods)
        {
            this._periods = new List<UZFPeriod>();
            for (int i = 0; i < nPeriods; i++)
            {
                UZFPeriod uzfP = new UZFPeriod(nrows, ncolumns);

                this._periods.Add(uzfP);

            }

            _IUZFBND = new int[nrows, ncolumns];
            _IRUNBND = new int[nrows, ncolumns];
            _VKS = new double[nrows, ncolumns];
            _EPS = new double[nrows, ncolumns];
            _THIS = new double[nrows, ncolumns];
            _THTI = new double[nrows, ncolumns];

            for (int i = 0; i < nrows; i++)
            {
                for (int j = 0; j < ncolumns; j++)
                {
                    _IUZFBND[i, j] = 1;
                    _IRUNBND[i, j] = 0;
                    _VKS[i, j] = 1.0;
                    _EPS[i, j] = 3.5;
                    _THIS[i, j] = 0.3;
                    _THTI[i, j] = 0.2;

                }
            }


        }
        #endregion



        #region 字段属性


        string _title = "#HuanAnKeJi UZF File";
        /// <summary>
        /// 标题  本软件固定使用上述标题
        /// </summary>
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }



        int _NUZTOP = 3;
        /// <summary>
        /// 补给和排放选项 
        /// =1，补给和排放仅在模型顶层，这个选项假定陆地表面为顶层
        /// =2，补给和排放发生在特定层，层好由 IUZFBND 定义，假定陆地表面
        /// =3，补给和排放发生在最上面的激活的单元内，一个定水头可以打破任何补给和排放并阻止任何渗漏
        /// </summary>
        public int NUZTOP
        {
            get { return _NUZTOP; }
            set { _NUZTOP = value; }
        }


        int _IUZFOPT = 2;
        /// <summary>
        /// 绝对值=1，垂向水力导水系数列在uzf1中使用 VKs变量
        /// 绝对值=2，表明垂向水力导水系数列在bcf或者lpf包中，如果使用bcf包，则IUZFOPT的绝对值=1，如果IUZFOPt=-1或者=-2，则神六去的非饱和流忽略
        /// </summary>
        public int IUZFOPT
        {
            get { return _IUZFOPT; }
            set { _IUZFOPT = value; }
        }


        bool _IRUNFLG = false;
        /// <summary>
        /// false =0,表面水排放到陆地表面分流道径流段或湖泊
        /// 
        /// </summary>
        public bool IRUNFLG
        {
            get { return _IRUNFLG; }
            set { _IRUNFLG = value; }
        }


        bool _IETFLG = false;
        /// <summary>
        /// false =0,蒸散ET不被模拟，反之则模拟
        /// </summary>
        public bool IETFLG
        {
            get { return _IETFLG; }
            set { _IETFLG = value; }
        }



        int _NTRAIL2 = 10;
        /// <summary>
        /// 尾波的数目，尾波用来定义跟随在入渗率之后含水量的剖面。尾波的数目依赖于实际，
        /// 但一个10-20之间的值通常是足够的。值越大会降低均衡误差但会增加内存
        /// </summary>
        public int NTRAIL2
        {
            get { return _NTRAIL2; }
            set { _NTRAIL2 = value; }
        }

        int _NSETS2 = 20;
        /// <summary>
        /// wave sets的数目  用来模拟多个入渗率时期，对于大多数问题来说值等于20.最大值不能超过NTRAIL2*NSETS2。
        /// 
        /// </summary>
        public int NSETS2
        {
            get { return _NSETS2; }
            set { _NSETS2 = value; }
        }



        double _SURFDEP = 1.0;
        /// <summary>
        /// 波动的高度
        /// </summary>
        public double SURFDEP
        {
            get { return _SURFDEP; }
            set { _SURFDEP = value; }
        }

        bool _isHaveTransient;
        /// <summary>
        /// 是否为瞬态应力期，默认为F
        /// </summary>
        public bool IsHaveTransient
        {
            get { return _isHaveTransient; }
            set { _isHaveTransient = value; }
        }

        //暂时缺乏  打印   的部分设置 ，不知道今后是否会添加此需求





        List<UZFPeriod> _periods;

        public List<UZFPeriod> Periods
        {
            get { return _periods; }
            set { _periods = value; }
        }




        //6种

        int[,] _IUZFBND;
        /// <summary>
        /// 补给和排放发生的单元
        /// </summary>
        public int[,] IUZFBND
        {
            get { return _IUZFBND; }
            set { _IUZFBND = value; }
        }

        int[,] _IRUNBND;

        public int[,] IRUNBND
        {
            get { return _IRUNBND; }
            set { _IRUNBND = value; }
        }

        double[,] _VKS;

        public double[,] VKS
        {
            get { return _VKS; }
            set { _VKS = value; }
        }

        double[,] _EPS;

        public double[,] EPS
        {
            get { return _EPS; }
            set { _EPS = value; }
        }

        double[,] _THIS;

        public double[,] THIS
        {
            get { return _THIS; }
            set { _THIS = value; }
        }

        double[,] _THTI;

        public double[,] THTI
        {
            get { return _THTI; }
            set { _THTI = value; }
        }







        #endregion


        #region 公共方法


        public void OnResetSperiods(int nPeriods)
        {
            if (this.NPeriods == nPeriods)
            {
                return;
            }
            if (this.NPeriods < nPeriods)
            {
                int nSub = nPeriods - this.NPeriods;

                for (int i = 0; i < nSub; i++)
                {
                    this.Periods.Add(new UZFPeriod(this.RCount, this.CCount));
                }
            }

            else
            {
                int nSub = this.NPeriods - nPeriods;
                this.Periods.RemoveRange(nPeriods, nSub);
            }

            this.NPeriods = nPeriods;
        }





        #endregion


        #region 内部方法


        #endregion

        #region ICloneable
        public object Clone()
        {
            UZF newUZF = (UZF)this.MemberwiseClone();


            newUZF.Periods = new List<UZFPeriod>();
            foreach (UZFPeriod item in this.Periods)
            {
                newUZF.Periods.Add((UZFPeriod) item.Clone());
            }
            //newUZF.Periods.AddRange(this.Periods);

            newUZF._IUZFBND = (int[,])this._IUZFBND.Clone();
            newUZF._IRUNBND = (int[,])this._IRUNBND.Clone();
            newUZF._VKS = (double[,])this._VKS.Clone();
            newUZF._EPS = (double[,])this._EPS.Clone();
            newUZF._THIS = (double[,])this._THIS.Clone();
            newUZF._THTI = (double[,])this._THTI.Clone();

            return newUZF;

        }
        #endregion

    }


}
